#include <stdlib.h>
#include <string.h>
#include <unordered_map>
#include <cstring>
#include <algorithm>
#include <mutex>
#include <vector>
#include <chrono>

#include "base_memory_pool.h"
#include "base_log.h"

namespace El {
namespace Base {

// 初始化静态成员变量
std::mutex MemoryPool::instancesMutex_;
std::unordered_map<std::string, std::unique_ptr<MemoryPool>> MemoryPool::instances_;

MemoryPool &MemoryPool::GetInstance(const std::string &name)
{
    std::lock_guard<std::mutex> lock(instancesMutex_);
    auto it = instances_.find(name);
    if (it != instances_.end()) {
        return *(it->second);
    }

    // 如果不存在，创建新实例
    auto newInstance = std::unique_ptr<MemoryPool>(new MemoryPool());
    MemoryPool &instance = *newInstance;
    instances_[name] = std::move(newInstance);
    LOG_DEBUG("Created new MemoryPool instance: {}", name);
    return instance;
}

bool MemoryPool::ReleaseInstance(const std::string &name)
{
    std::lock_guard<std::mutex> lock(instancesMutex_);
    auto it = instances_.find(name);
    if (it != instances_.end()) {
        instances_.erase(it);
        LOG_DEBUG("Released MemoryPool instance: {}", name);
        return true;
    }
    return false;
}

void MemoryPool::ReleaseAllInstances()
{
    std::lock_guard<std::mutex> lock(instancesMutex_);
    instances_.clear();
    LOG_DEBUG("Released all MemoryPool instances");
}

/**
 * @brief 内存池内部结构
 */
struct MemoryPool::Internal {
    uint8_t *buffer_;     // 内存池缓冲区指针
    uint64_t totalSize_;  // 内存池总大小
    uint64_t used_;       // 已使用的内存大小
    uint64_t current_;    // 当前分配位置的偏移量
    uint64_t freeOffset_; // 释放位置的偏移量
    uint64_t blockAlign_; // 内存块对齐大小

    // 使用哈希表跟踪已分配的内存块
    std::unordered_map<void *, uint64_t> allocatedBlocks_; // 指针 -> 大小的映射

    // 跟踪内存区域的使用情况，用于支持非顺序释放
    std::unordered_map<uint64_t, uint64_t> usedRegions_; // 起始偏移量 -> 大小的映射
};

MemoryPool::MemoryPool()
    : internal_(nullptr),
      totalAllocatedSize_(0),
      allocationsInCurrentWindow_(0),
      currentAllocationRate_(0),
      lastUpdateTime_(std::chrono::steady_clock::now())
{
    LOG_DEBUG("MemoryPool constructor called");
}

MemoryPool::~MemoryPool()
{
    if (internal_) {
        if (internal_->buffer_) {
            free(internal_->buffer_);
            internal_->buffer_ = nullptr;
        }
        delete internal_;
        internal_ = nullptr;
    }
}

bool MemoryPool::Init(uint64_t totalSize, uint64_t blockAlign)
{
    std::lock_guard<std::mutex> lock(mutex_);

    // 如果已经初始化，先清理现有资源
    if (internal_) {
        if (internal_->buffer_) {
            free(internal_->buffer_);
        }
        delete internal_;
        internal_ = nullptr;
    }

    if (totalSize == 0) {
        LOG_ERROR("MemoryPool Init failed: totalSize cannot be 0");
        return false;
    }

    if (blockAlign == 0) {
        blockAlign = 8; // 默认为8字节对齐
    }

    // 确保blockAlign是2的幂次方
    if ((blockAlign & (blockAlign - 1)) != 0) {
        LOG_WARN("MemoryPool: blockAlign {} is not a power of 2, adjusted", blockAlign);
        // 调整为下一个2的幂次方
        uint64_t power = 1;
        while (power < blockAlign) {
            power <<= 1;
        }
        blockAlign = power;
    }

    // 分配内存池结构
    internal_ = new Internal();
    if (!internal_) {
        LOG_ERROR("MemoryPool Init failed: cannot allocate internal structure");
        return false;
    }

    // 分配内存池缓冲区
    internal_->buffer_ = (uint8_t *)malloc(totalSize);
    if (!internal_->buffer_) {
        LOG_ERROR("MemoryPool Init failed: cannot allocate memory pool buffer of size {}", totalSize);
        delete internal_;
        internal_ = nullptr;
        return false;
    }

    // 初始化内存池
    internal_->totalSize_ = totalSize;
    internal_->used_ = 0;
    internal_->current_ = 0;
    internal_->freeOffset_ = 0;
    internal_->blockAlign_ = blockAlign;
    internal_->allocatedBlocks_.clear();
    internal_->usedRegions_.clear();

    // 重置统计数据
    totalAllocatedSize_ = 0;
    allocationsInCurrentWindow_ = 0;
    currentAllocationRate_ = 0;
    lastUpdateTime_ = std::chrono::steady_clock::now();

    LOG_INFO("MemoryPool initialized: size={}, blockAlign={}", totalSize, blockAlign);
    return true;
}

// 检查指定区域是否与已分配区域重叠
bool MemoryPool::IsRegionOverlapping(uint64_t start, uint64_t size)
{
    if (!internal_) {
        return false;
    }

    uint64_t end = start + size;

    for (const auto &region : internal_->usedRegions_) {
        uint64_t regionStart = region.first;
        uint64_t regionEnd = regionStart + region.second;

        // 检查是否有重叠
        if (!(end <= regionStart || start >= regionEnd)) {
            return true;
        }
    }

    return false;
}

// 查找可用的内存区域
bool MemoryPool::FindAvailableRegion(uint64_t size, uint64_t &outOffset)
{
    if (!internal_) {
        return false;
    }

    // 首先尝试从当前位置分配
    if (internal_->current_ + size <= internal_->totalSize_ && !IsRegionOverlapping(internal_->current_, size)) {
        outOffset = internal_->current_;
        return true;
    }

    // 如果当前位置不可用，尝试从头开始查找
    // 但只有当前面没有已分配的内存块时，才能从头开始分配
    if (size <= internal_->totalSize_) {
        // 检查从头开始到第一个已分配区域之间是否有足够空间
        uint64_t firstUsedOffset = internal_->totalSize_;

        // 找到第一个已分配区域的偏移量
        for (const auto &region : internal_->usedRegions_) {
            if (region.first < firstUsedOffset) {
                firstUsedOffset = region.first;
            }
        }

        // 如果从头到第一个已分配区域有足够空间，则可以从头开始分配
        if (firstUsedOffset >= size && !IsRegionOverlapping(0, size)) {
            outOffset = 0;
            LOG_DEBUG("MemoryPool: Wrapped around to beginning of pool");
            return true;
        }
    }

    // 如果无法分配，返回失败
    LOG_DEBUG("MemoryPool: Cannot allocate memory at current position or from beginning, allocation failed");
    return false;
}

void MemoryPool::UpdateAllocationRate(uint64_t size)
{
    // 更新累计分配总量
    totalAllocatedSize_ += size;

    // 更新当前时间窗口的分配量
    allocationsInCurrentWindow_ += size;

    // 检查是否需要更新速率
    auto now = std::chrono::steady_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastUpdateTime_).count();

    // 如果已经过了更新间隔，计算新的速率
    if (elapsed >= rateUpdateInterval_.count() * 1000) {
        // 计算每秒分配速率 (字节/秒)
        currentAllocationRate_ = static_cast<uint64_t>(allocationsInCurrentWindow_ * 1000.0 / elapsed);

        // 重置计数器和时间点
        allocationsInCurrentWindow_ = 0;
        lastUpdateTime_ = now;
    }
}

void *MemoryPool::Allocate(uint64_t size)
{
    std::lock_guard<std::mutex> lock(mutex_);

    if (!internal_ || !internal_->buffer_) {
        LOG_ERROR("MemoryPool not initialized correctly");
        return nullptr;
    }

    if (size == 0) {
        LOG_WARN("MemoryPool: Attempted to allocate 0 bytes, returning nullptr");
        return nullptr;
    }

    // 计算对齐后的大小
    uint64_t alignedSize = (size + internal_->blockAlign_ - 1) & ~(internal_->blockAlign_ - 1);

    // 检查是否超过内存池总大小
    if (alignedSize > internal_->totalSize_) {
        LOG_ERROR("MemoryPool: Requested size {} (aligned to {}) exceeds total pool size {}", size, alignedSize,
                  internal_->totalSize_);
        return nullptr;
    }

    // 检查是否有足够的可用空间
    if (internal_->used_ + alignedSize > internal_->totalSize_) {
        LOG_DEBUG("MemoryPool: Not enough total space available, allocation failed");
        return nullptr;
    }

    // 查找可用区域
    uint64_t offset;
    if (!FindAvailableRegion(alignedSize, offset)) {
        LOG_ERROR("MemoryPool: Cannot find available region for size {}", alignedSize);
        return nullptr;
    }

    // 获取分配的内存地址
    void *memory = internal_->buffer_ + offset;

    // 更新当前位置和已使用大小
    internal_->current_ = offset + alignedSize;
    internal_->used_ += alignedSize;

    // 记录分配的块
    internal_->allocatedBlocks_[memory] = alignedSize;
    internal_->usedRegions_[offset] = alignedSize;

    // 更新内存分配统计
    UpdateAllocationRate(alignedSize);

    LOG_DEBUG("MemoryPool: Allocated {} bytes (aligned to {}) at offset {}", size, alignedSize, offset);

    return memory;
}

bool MemoryPool::Free(void *ptr)
{
    std::lock_guard<std::mutex> lock(mutex_);

    if (!internal_ || !internal_->buffer_ || !ptr) {
        LOG_ERROR("MemoryPool not initialized correctly or null pointer");
        return false;
    }

    uint8_t *address = static_cast<uint8_t *>(ptr);

    // 检查指针是否在内存池范围内
    if (address < internal_->buffer_ || address >= internal_->buffer_ + internal_->totalSize_) {
        LOG_ERROR("MemoryPool: Attempted to free memory outside of pool");
        return false;
    }

    // 查找分配的块
    auto it = internal_->allocatedBlocks_.find(ptr);
    if (it == internal_->allocatedBlocks_.end()) {
        LOG_ERROR("MemoryPool: Attempted to free unallocated memory at offset {}", address - internal_->buffer_);
        return false;
    }

    // 获取实际分配的大小（对齐后的大小）
    uint64_t alignedSize = it->second;
    uint64_t offset = address - internal_->buffer_;

    // 从已分配块列表中移除
    internal_->allocatedBlocks_.erase(it);

    // 从已使用区域中移除
    auto regionIt = internal_->usedRegions_.find(offset);
    if (regionIt != internal_->usedRegions_.end()) {
        internal_->usedRegions_.erase(regionIt);
    }

    // 更新已使用大小
    internal_->used_ -= alignedSize;

    // 如果所有内存都已释放，重置指针
    if (internal_->used_ == 0) {
        internal_->current_ = 0;
        internal_->freeOffset_ = 0;
    }

    LOG_DEBUG("MemoryPool: Freed {} bytes at offset {}", alignedSize, offset);
    return true;
}

uint64_t MemoryPool::GetTotalSize() const
{
    if (!internal_) {
        return 0;
    }
    return internal_->totalSize_;
}

uint64_t MemoryPool::GetAvailableSize() const
{
    if (!internal_) {
        return 0;
    }
    // 返回总大小减去已使用大小
    return internal_->totalSize_ - internal_->used_;
}

uint64_t MemoryPool::GetUsedSize() const
{
    if (!internal_) {
        return 0;
    }
    return internal_->used_;
}

void MemoryPool::Reset()
{
    std::lock_guard<std::mutex> lock(mutex_);

    if (!internal_) {
        return;
    }

    internal_->current_ = 0;
    internal_->freeOffset_ = 0;
    internal_->used_ = 0;
    internal_->allocatedBlocks_.clear();
    internal_->usedRegions_.clear();

    LOG_DEBUG("MemoryPool: Reset to initial state");
}

void MemoryPool::DumpStatus(bool detailed) const
{
    if (!internal_) {
        LOG_INFO("MemoryPool: Not initialized");
        return;
    }

    // 计算内存使用率
    double usagePercent = 0.0;
    if (internal_->totalSize_ > 0) {
        usagePercent = (double)internal_->used_ / internal_->totalSize_ * 100.0;
    }

    // 转换为KB单位
    double totalSizeKB = internal_->totalSize_ / 1024.0;
    double usedSizeKB = internal_->used_ / 1024.0;
    double availableSizeKB = (internal_->totalSize_ - internal_->used_) / 1024.0;
    double totalAllocatedSizeKB = totalAllocatedSize_ / 1024.0;
    double allocationRateKBPerSec = currentAllocationRate_ / 1024.0;

    // 打印基本信息
    LOG_INFO("=== MemoryPool Status ===");
    LOG_INFO("Total Size: {:.2f} KB", totalSizeKB);
    LOG_INFO("Used Size: {:.2f} KB ({:.2f}%)", usedSizeKB, usagePercent);
    LOG_INFO("Available Size: {:.2f} KB", availableSizeKB);

    // 添加内存使用率进度条
    const int barWidth = 50; // 进度条宽度
    int filledWidth = static_cast<int>(usagePercent / 100.0 * barWidth);
    std::string progressBar = "[";
    for (int i = 0; i < barWidth; ++i) {
        if (i < filledWidth) {
            progressBar += "■"; // 已使用部分用实心方块表示
        } else {
            progressBar += "□"; // 未使用部分用空心方块表示
        }
    }
    progressBar += "]";
    LOG_INFO("Memory Usage: {} {:.2f}%", progressBar, usagePercent);

    LOG_INFO("Current Allocation Position: {} bytes offset", internal_->current_);
    LOG_INFO("Block Alignment: {} bytes", internal_->blockAlign_);
    LOG_INFO("Allocated Blocks Count: {}", internal_->allocatedBlocks_.size());
    LOG_INFO("Used Regions Count: {}", internal_->usedRegions_.size());

    // 打印统计信息
    LOG_INFO("Total Allocated Size (historical): {:.2f} KB", totalAllocatedSizeKB);
    LOG_INFO("Current Allocation Rate: {:.2f} KB/sec", allocationRateKBPerSec);

    // 如果需要详细信息，打印每个已分配内存块的详情
    if (detailed) {
        LOG_INFO("--- Allocated Blocks Details ---");

        // 创建一个按偏移量排序的内存块列表
        std::vector<std::pair<uint64_t, uint64_t>> sortedBlocks;
        for (const auto &region : internal_->usedRegions_) {
            sortedBlocks.push_back(std::make_pair(region.first, region.second));
        }

        // 按偏移量排序
        std::sort(sortedBlocks.begin(), sortedBlocks.end(),
                  [](const std::pair<uint64_t, uint64_t> &a, const std::pair<uint64_t, uint64_t> &b) {
                      return a.first < b.first;
                  });

        // 打印每个内存块的信息
        for (size_t i = 0; i < sortedBlocks.size(); ++i) {
            uint64_t offset = sortedBlocks[i].first;
            uint64_t size = sortedBlocks[i].second;
            uint64_t endOffset = offset + size - 1;

            LOG_INFO("Block #{}: Offset={}, Size={}, End={}", i + 1, offset, size, endOffset);
        }

        // 添加内存块分布图
        if (!sortedBlocks.empty()) {
            LOG_INFO("--- Memory Block Distribution ---");

            // 计算内存池的可视化表示
            const int mapWidth = 80; // 可视化图宽度
            std::string memoryMap = "";

            // 创建内存池的可视化表示
            for (int i = 0; i < mapWidth; ++i) {
                uint64_t position = (uint64_t)((double)i / mapWidth * internal_->totalSize_);
                bool isAllocated = false;

                // 检查该位置是否在已分配的内存块中
                for (const auto &block : sortedBlocks) {
                    if (position >= block.first && position < block.first + block.second) {
                        isAllocated = true;
                        break;
                    }
                }

                if (isAllocated) {
                    memoryMap += "■"; // 已分配区域
                } else {
                    memoryMap += "□"; // 未分配区域
                }
            }

            LOG_INFO("Memory Map: {}", memoryMap);
            LOG_INFO("Legend: ■ = Allocated, □ = Free");

            // 为每个内存块创建可视化表示
            LOG_INFO("--- Individual Block Visualization ---");
            for (size_t i = 0; i < sortedBlocks.size(); ++i) {
                uint64_t offset = sortedBlocks[i].first;
                uint64_t size = sortedBlocks[i].second;
                double startPercent = (double)offset / internal_->totalSize_ * 100.0;
                double sizePercent = (double)size / internal_->totalSize_ * 100.0;

                // 创建块的可视化表示
                int blockStart = static_cast<int>(startPercent / 100.0 * mapWidth);
                int blockWidth = std::max(1, static_cast<int>(sizePercent / 100.0 * mapWidth));

                std::string blockVis = "";
                for (int j = 0; j < mapWidth; ++j) {
                    if (j >= blockStart && j < blockStart + blockWidth) {
                        blockVis += "■"; // 当前块
                    } else {
                        blockVis += " "; // 空白
                    }
                }

                LOG_INFO("Block #{}: {} (Offset: {:.2f}%, Size: {:.2f}%)", i + 1, blockVis, startPercent, sizePercent);
            }
        }

        // 分析内存碎片情况
        if (!sortedBlocks.empty()) {
            // 计算碎片数量（不连续的内存块之间的空隙）
            int fragmentCount = 0;
            uint64_t totalFragmentSize = 0;
            std::vector<std::pair<uint64_t, uint64_t>> fragments; // 存储碎片的起始位置和大小

            for (size_t i = 1; i < sortedBlocks.size(); ++i) {
                uint64_t prevEnd = sortedBlocks[i - 1].first + sortedBlocks[i - 1].second;
                uint64_t currStart = sortedBlocks[i].first;

                if (prevEnd < currStart) {
                    fragmentCount++;
                    uint64_t fragmentSize = currStart - prevEnd;
                    totalFragmentSize += fragmentSize;
                    fragments.push_back(std::make_pair(prevEnd, fragmentSize));
                    LOG_INFO("Fragment between blocks #{} and #{}: Size={} bytes", i, i + 1, fragmentSize);
                }
            }

            // 检查最后一个块之后到内存池末尾是否有未使用空间
            if (!sortedBlocks.empty()) {
                uint64_t lastEnd = sortedBlocks.back().first + sortedBlocks.back().second;
                if (lastEnd < internal_->totalSize_) {
                    fragmentCount++;
                    uint64_t fragmentSize = internal_->totalSize_ - lastEnd;
                    totalFragmentSize += fragmentSize;
                    fragments.push_back(std::make_pair(lastEnd, fragmentSize));
                    LOG_INFO("Fragment after last block: Size={} bytes", fragmentSize);
                }
            }

            // 检查第一个块之前是否有未使用空间
            if (!sortedBlocks.empty() && sortedBlocks.front().first > 0) {
                fragmentCount++;
                uint64_t fragmentSize = sortedBlocks.front().first;
                totalFragmentSize += fragmentSize;
                fragments.push_back(std::make_pair(0, fragmentSize));
                LOG_INFO("Fragment before first block: Size={} bytes", fragmentSize);
            }

            LOG_INFO("Total Fragments: {}, Total Fragment Size: {} bytes", fragmentCount, totalFragmentSize);

            // 添加碎片分布图
            if (!fragments.empty()) {
                LOG_INFO("--- Fragment Distribution ---");

                const int mapWidth = 80; // 可视化图宽度
                std::string fragmentMap = "";

                // 创建碎片的可视化表示
                for (int i = 0; i < mapWidth; ++i) {
                    uint64_t position = (uint64_t)((double)i / mapWidth * internal_->totalSize_);
                    bool isFragment = false;

                    // 检查该位置是否在碎片中
                    for (const auto &frag : fragments) {
                        if (position >= frag.first && position < frag.first + frag.second) {
                            isFragment = true;
                            break;
                        }
                    }

                    if (isFragment) {
                        fragmentMap += "▒"; // 碎片区域
                    } else {
                        fragmentMap += " "; // 非碎片区域
                    }
                }

                LOG_INFO("Fragment Map: {}", fragmentMap);
                LOG_INFO("Legend: ▒ = Fragment");

                // 计算碎片率
                double fragmentationRatio = (double)totalFragmentSize / internal_->totalSize_ * 100.0;
                LOG_INFO("Fragmentation Ratio: {:.2f}%", fragmentationRatio);

                // 碎片率进度条
                int fragFilledWidth = static_cast<int>(fragmentationRatio / 100.0 * barWidth);
                std::string fragBar = "[";
                for (int i = 0; i < barWidth; ++i) {
                    if (i < fragFilledWidth) {
                        fragBar += "▒"; // 碎片部分
                    } else {
                        fragBar += " "; // 非碎片部分
                    }
                }
                fragBar += "]";
                LOG_INFO("Fragmentation: {} {:.2f}%", fragBar, fragmentationRatio);
            }
        }
    }

    LOG_INFO("=== End of MemoryPool Status ===");
}

} // namespace Base
} // namespace El
